home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993 October: Windmill on DISC / ADC Developer CD (1993-10) (''Windmill On DISC'')_iso / Dev.CD Oct 93.iso / System Software / U.S. System Software / System 7 Pro™ Beta 11 / Development Tools / Sample Code / Messaging Service Access Module / Internet PMSAM / Internet PMSAM source / gatewayevents.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-28  |  9.8 KB  |  393 lines  |  [TEXT/MPS ]

  1. /*-------------------------------------------------------------------
  2.  
  3. AOCE Post Office Protocol (POP) / Simple Mail Transfer Protocol (SMTP)
  4. Mail Service Access Module
  5.  
  6. written by Steve Falkenburg-- MacDTS
  7. ©1991-1993 Apple Computer, Inc.
  8.  
  9. --------------
  10. change history
  11. --------------
  12.  
  13. SJF        02/19/93    update for beta build    b1
  14. SJF        10/29/92    update to a11            a11
  15. SJF        06/08/92    update to a8            a8
  16. SJF        02/15/92    first working version    a4.5
  17. SJF        10/16/91    initial coding            a3
  18.  
  19. ---------------------------------------------------------------------*/
  20.  
  21. #ifndef __TYPES__
  22. #include <Types.h>
  23. #endif
  24.  
  25. #ifndef __PROCESSES__
  26. #include <Processes.h>
  27. #endif
  28.  
  29. #ifndef __OCE__
  30. #include <OCE.h>
  31. #endif
  32.  
  33. #ifndef __OCEERRORS__
  34. #include <OCEErrors.h>
  35. #endif
  36.  
  37. #include "const.h"
  38. #include "gwerrors.h"
  39. #include "mytypes.h"
  40. #include "globals.h"
  41. #include "utils.h"
  42. #include "gatewaystuff.h"
  43. #include "gatewayget.h"
  44. #include "gatewayput.h"
  45.  
  46. #include "gatewayevents.h"
  47.  
  48.  
  49. // DoGatewayEvent
  50. //
  51. // handles high level events passed from the AOCE toolbox to the MSAM
  52. //
  53. // input: messageID       -- identifies the high level event
  54. //        mailEPPC        -- mail EPPC message area containing shared mem area and msg seq number
  55. //        slotID          -- slot ID (if used)
  56. //        inMainEventLoop -- true if we're being called from our main event loop
  57. //
  58. // on exit, the result field of the SMCA is set to the appropriate error code, indicating
  59. // that the MSAM is done processing the event
  60. //
  61. // note: I removed the EPPC handlers for MailboxOpened, MailboxClosed, and SendImmediate, as
  62. //       they are no longer of value to the MSAM
  63. //
  64. // note: only CreateSlot, ModifySlot, DeleteSlot and message opened EPPCs are reliable
  65. //       all others are informational only and may not always be sent (no guarantees)
  66. //
  67. // online gateway note: we do not handle kMailEPPCInQUpdate, kMailEPPCMsgOpened
  68. //       since we are not an online gateway
  69. //
  70. OSErr DoGatewayEvent(long messageID,MailEPPCMsg *mailEPPC,short slotID,Boolean inMainEventLoop)
  71. {
  72.     OSErr err;
  73.     
  74.     if (mailEPPC && mailEPPC->version != kMailEPPCMsgVersion)    // check version of smca
  75.         return kOCEVersionErr;
  76.  
  77.     err = noErr;
  78.     
  79.     switch (messageID) {
  80.  
  81.         // create a new slot
  82.         case kMailEPPCCreateSlot:
  83.             err = CreateSlot(gMSAMCID,mailEPPC->u.theSMCA->u.slotCID);
  84.             mailEPPC->u.theSMCA->result = err;
  85.             break;
  86.  
  87.         // modify the contents of an existing slot
  88.         case kMailEPPCModifySlot:
  89.             err = ModifySlot(gMSAMCID,GetSlotSpecFromID(slotID),mailEPPC->u.theSMCA->u.slotCID);
  90.             mailEPPC->u.theSMCA->result = err;
  91.             break;
  92.  
  93.         // delete an existing slot
  94.         case kMailEPPCDeleteSlot:
  95.             err = DeleteSlot(gMSAMCID,GetSlotSpecFromID(slotID));
  96.             mailEPPC->u.theSMCA->result = err;
  97.             break;
  98.  
  99.         // shut down the gateway
  100.         case kMailEPPCShutDown:
  101.             err = ShutDownServer();
  102.             break;
  103.  
  104.         // instructs the gateway to continue operation after previously suspending itself
  105.         case kMailEPPCContinue:
  106.             if (slotID==0)
  107.                 err = ContinueOperation(nil);
  108.             else
  109.                 err = ContinueOperation(GetSlotSpecFromID(slotID));
  110.             break;
  111.         
  112.         // informs a gateway that it's time to wake up (when a mail check timer expires)
  113.         case kMailEPPCSchedule:
  114.             if (inMainEventLoop)
  115.                 err = TimeToCheckForMail();
  116.             else {
  117.                 err = EnqueueHighLevelEvent(kMailEPPCSchedule,nil,slotID);
  118.             }
  119.             break;
  120.         
  121.         // instructs a gateway to update its incoming queue (for post-its)
  122.         case kMailEPPCInQUpdate:
  123.             mailEPPC->u.theSMCA->result = noErr;    // don't handle, since we're not online
  124.             break;
  125.         
  126.         // instructs a gateway that a message was opened (for post-its)
  127.         case kMailEPPCMsgOpened:
  128.             mailEPPC->u.theSMCA->result = noErr;    // don't handle, since we're not online
  129.             break;
  130.         
  131.         // instructs a gateway to wake up due to an external event (something bad happened)
  132.         case kMailEPPCWakeup:
  133.             err = WakeupFromExternalEvent();
  134.             break;
  135.         
  136.         // notification that gateway has a letter in outgoing queue
  137.         case kMailEPPCMsgPending:
  138.             if (inMainEventLoop)
  139.                 err = MessagePending(GetSlotSpecFromID(slotID));
  140.             else {
  141.                 err = EnqueueHighLevelEvent(kMailEPPCMsgPending,nil,slotID);
  142.             }
  143.             break;
  144.  
  145.         case kMailEPPCSendImmediate:
  146.             // should save away sequence number to send now
  147.             // also should force sending now…
  148.             mailEPPC->u.theSMCA->result = noErr;    // don't handle, since we're not online
  149.             break;
  150.  
  151.         case kMailEPPCLocationChanged:
  152.             // look at MailLocationInfo
  153.             // we don't support new locations for "i'm at"
  154.             break;
  155.  
  156.         // these aren't handled
  157.         case kMailEPPCMailboxOpened:
  158.         case kMailEPPCMailboxClosed:
  159.         case kMailEPPCDeleteOutQMsg:
  160.             err = noErr;
  161.             break;
  162.             
  163.         // unsupported high level event
  164.         defaut:
  165.             err = kUndefinedHighLevelEvent;
  166.             break;
  167.     }
  168.             
  169.     return err;
  170. }
  171.  
  172.  
  173. OSErr EnqueueHighLevelEvent(long messageID,MailEPPCMsg *mailEPPC,short slotID)
  174. {
  175.     HLEventQ *newEl;
  176.     
  177.     newEl = NewPtrChk(sizeof(HLEventQ));
  178.     if (MemError()!=noErr)
  179.         return MemError();
  180.     
  181.     newEl->messageID = messageID;
  182.     newEl->mailEPPC = mailEPPC;
  183.     newEl->slotID = slotID;
  184.             
  185.     newEl->next = gHLEventAdd;
  186.     newEl->prev = nil;
  187.     gHLEventAdd->prev = newEl;
  188.     gHLEventAdd = newEl;
  189.     if (gHLEventRemove==nil)
  190.         gHLEventRemove = newEl;
  191.  
  192.     return noErr;    
  193. }
  194.  
  195.  
  196. Boolean DequeueHighLevelEvent(long *messageID,MailEPPCMsg **mailEPPC,short *slotID)
  197. {
  198.     HLEventQ *oldQ;
  199.     
  200.     if (!gHLEventRemove)
  201.         return false;
  202.     
  203.     *messageID = gHLEventRemove->messageID;
  204.     *mailEPPC = gHLEventRemove->mailEPPC;
  205.     *slotID = gHLEventRemove->slotID;
  206.     
  207.     oldQ = gHLEventRemove;
  208.     gHLEventRemove = gHLEventRemove->prev;
  209.     if (gHLEventRemove)
  210.         gHLEventRemove->next = nil;
  211.     else
  212.         gHLEventAdd = nil;
  213.     
  214.     DisposPtrChk(oldQ);
  215.     
  216.     return true;
  217. }
  218.  
  219.  
  220. OSErr ProcessQueuedEvents(void)
  221. {
  222.     long messageID;
  223.     MailEPPCMsg *mailEPPC;
  224.     short slotID;
  225.     OSErr err;
  226.     
  227.     err = noErr;
  228.     while (DequeueHighLevelEvent(&messageID,&mailEPPC,&slotID) && err==noErr) {
  229.         err = DoGatewayEvent(messageID,mailEPPC,slotID,true);
  230.     }
  231.     return err;
  232. }
  233.  
  234.  
  235. // CreateSlot
  236. //
  237. // high level call to process the Create Slot high level event
  238. //
  239. // inputs: msamCID      -- creation ID of the MSAM setup record
  240. //         slotCID      -- creation ID of the new slot information
  241. //
  242. OSErr CreateSlot(CreationID msamCID,CreationID slotCID)
  243. {
  244.     #pragma unused (msamCID)
  245.     OSErr err;
  246.     short slotID;
  247.     
  248.     TraceExecution("\pCreateSlot");
  249.     
  250.     // add SlotID to mailservice record
  251.     
  252.     slotID = 1;    // we only have 1 slot for now, so it is always ID 1
  253.     
  254.     err = AddAttribute(&slotCID,gAOCESetupDSRef,OCEGetIndAttributeType(kSlotIDAttrTypeNum),
  255.                     &slotID,sizeof(short),typeBinary);
  256.     if (err!=noErr)
  257.         return err;
  258.     
  259.     MarkSlotInformationDirty();    // mark that slots need to be updated at main event time
  260.     return noErr;
  261. }
  262.  
  263.  
  264. // ModifySlot
  265. //
  266. // high level call to process the Modify Slot high level event
  267. //
  268. // inputs: msamCID      -- creation ID of the MSAM setup record
  269. //         slot         -- slot specifier for the slot being modified
  270. //         slotCID      -- creation ID of the modified slot information
  271. //
  272. OSErr ModifySlot(CreationID msamCID,SlotSpec *slot,CreationID slotCID)
  273. {
  274.     #pragma unused (msamCID,slot,slotCID)
  275.     
  276.     TraceExecution("\pModifySlot");
  277.     
  278.     MarkSlotInformationDirty();    // mark that slots need to be updated at main event time
  279.     return noErr;
  280. }
  281.  
  282.  
  283. // DeleteSlot
  284. //
  285. // high level call to process the Delete Slot high level event
  286. //
  287. // inputs: msamCID      -- creation ID of the MSAM setup record
  288. //         slot         -- slot specifier for the slot being deleted
  289. //
  290. OSErr DeleteSlot(CreationID msamCID,SlotSpec *slot)
  291. {
  292.     #pragma unused(msamCID,slot)
  293.     
  294.     TraceExecution("\pDeleteSlot");
  295.     MarkSlotInformationDirty();    // mark that slots need to be updated at main event time
  296.     return noErr;
  297. }
  298.  
  299.  
  300. // ShutDownServer
  301. //
  302. // high level call to process the ShutDownServer high level event
  303. // sets gDone to true, indicating that we'll quit the next time through our event loop
  304. //
  305. OSErr ShutDownServer(void)
  306. {
  307.     TraceExecution("\pShutDownServer");
  308.     
  309.     gDone = true;
  310.     return noErr;
  311. }
  312.  
  313.  
  314. // MessagePending
  315. //
  316. // high level call to process the MessagePending high level event.
  317. // increments the number of messages pending counter on the slot the message is pending for.
  318. //
  319. OSErr MessagePending(SlotSpec *slot)
  320. {
  321.     OSErr err;
  322.     
  323.     TraceExecution("\pMessagePending");
  324.     
  325.     // if the slot isn't suspended, do the send now
  326.     
  327.     if (slot && slot->enabled)
  328.         err = DoSlotGet(slot);
  329.             
  330.     return err;
  331. }
  332.  
  333.  
  334. // ContinueOperation
  335. //
  336. // process continue high level event, which instructs a gateway to continue operation after
  337. // previously suspending itself.  it's permissible to have a gateway quit itself between
  338. // transactions.  if this is done, each time the gateway is launched, it will get a
  339. // continue eppc.
  340. //
  341. // input:    slot    contains the slot specification for the slot being resumed, or nil of
  342. //                    the continue applies to the entire gateway.
  343. //
  344. OSErr ContinueOperation(SlotSpec *slot)
  345. {
  346.     TraceExecution("\pContinueOperation");
  347.     
  348.     if (slot)
  349.         slot->enabled = true;
  350.         
  351.     return noErr;
  352. }
  353.  
  354.  
  355. // TimeToCheckForMail
  356. //
  357. // process schedule high level event, which is sent by the toolbox when the check for mail
  358. // timers specified in the slot configuration records expire.  this event makes it so the
  359. // gateway doesn't continually have to poll to see if the checking timers have expired
  360. //
  361. OSErr TimeToCheckForMail(void)
  362. {
  363.     OSErr err,err2;
  364.     
  365.     TraceExecution("\pTimeToCheckForMail");
  366.     
  367.     // do gets/puts for slots whose timers have expired
  368.     
  369.     err = PeriodicCheckGet();
  370.     err2 = PeriodicCheckPut();
  371.     
  372.     if (err==noErr)
  373.         err = err2;
  374.         
  375.     return err;
  376. }
  377.  
  378.  
  379. // WakeupFromExternalEvent
  380. //
  381. // process the wakeup high level event, which instructs a gateway to wake up due to
  382. // an external event that cannot be predicted by AOCE  if a gateway receives an
  383. // eppcWakeup event just after being launched, it syhould take that to mean that it
  384. // was launched in response to an external event.  if the gateway was al;ready running
  385. // when the event arrived, it is an indication that ian external event important to the 
  386. // gateway has occured.  the wakeup attempt is not reliable
  387. //
  388. OSErr WakeupFromExternalEvent(void)
  389. {
  390.     TraceExecution("\pWakeupFromExternalEvent");
  391.     return noErr;
  392. }
  393.